package de.bazinga.rotw.weapon.grenade;

import com.jme.input.MouseInput;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jmex.game.state.GameStateManager;

import de.bazinga.rotw.game.Game;
import de.bazinga.rotw.game.RotwGameState;
import de.bazinga.rotw.network.BasicSyncManager;
import de.bazinga.rotw.network.Client;
import de.bazinga.rotw.network.Server;
import de.bazinga.rotw.network.message.NewBulletMessage;
import de.bazinga.rotw.person.Person;
import de.bazinga.rotw.player.Player;
import de.bazinga.rotw.sound.Sound;
import de.bazinga.rotw.weapon.Weapon;

public abstract class Grenade extends Weapon {
	
	private int ammo = -1;
	protected long lastShoot = 0;
	
	
	protected static Node weaponModel = null;
	
	
	public Grenade() {
		this.ammo = 2;
	}
	
	
	public void updateWeapon(Player player) {
		// Fire?
		
		if(MouseInput.get().isButtonDown(0)) {
			BasicSyncManager syncManager = ((RotwGameState)GameStateManager.getInstance().getChild("gameState")).getSyncManager();
			
			NewBulletMessage newBulletMessage = new NewBulletMessage();
			newBulletMessage.setWeaponFlag(getWeaponFlag());
			newBulletMessage.setLocation(player.getCameraPosition().clone());
			newBulletMessage.setDirection(Game.getGame().getCamera().getDirection().clone());
			newBulletMessage.setBulletColor(player.getBulletColor());
			

			if(canFire()) {
				// Animate
				if(syncManager instanceof Server) {
					// Just Fire the bullet
					fireBullet(player,player.getCameraPosition().clone(), Game.getGame().getCamera().getDirection().clone(), false);
					player.fired();
					// Tell all the Clients we fired a Bullet
					((Server)syncManager).getServer().sendToAll(newBulletMessage);
				}else if(syncManager instanceof Client) {
					((Client) syncManager).getClient().sendToServer(newBulletMessage);
					player.fired();
				}
			}
		}
	}

	
	
	/**
	 * Only the Server will call this
	 */
	public void fireBullet(Person person, Vector3f location, Vector3f direction, boolean fromClient) {
		// Clean this up!!!

		//if(!fromClient) {
			GrenadeObject granade = null;
			granade = GrenadeList.getInstance().getUnusedGranade(
						this, 
						person,
						((RotwGameState)GameStateManager.getInstance().getChild("gameState")).getRootNode(), 
						location, 
						direction);
			GrenadeList.getInstance().addGranade(granade);
			// Tell the Player we fired!
			person.fired();
		//}
	}


	
	/**
	 * Can the player fire again?
	 * Checks if he can fire again and if he has enough Ammo (also subtracts ammo)
	 * @return
	 */
	public boolean canFire() {
		if((System.currentTimeMillis() - lastShoot) < 700 )
			return false;
		
		if(ammo == 0)
			return false;
		
		lastShoot = System.currentTimeMillis();
		
		ammo--;
		
		return true;
	}
	
	
	
	
	public String getIcon() {
		return "granade.png";
	}
	
	public Node getWeaponModel() {
		if(weaponModel == null) {
			weaponModel = new Node("weapon");
			// Load Model
		}
		return weaponModel;
	}


	
	public void playerFired() {
		if(Game.getGame().getSettings().isSFX()) {
			Sound.getInstance().getAudioTrack("sounds/fireInTheHole.wav").play();
		}
	}

	
	public int getAmmo() {
		return ammo;
	}


	public void setAmmo(int ammo) {
		this.ammo = ammo;
	}


	public void refillAmmo() {
		ammo = 2;
	}
	
	public float getSpeedFactor() {
		return 1.05f;
	}
	
	public abstract void handleCollision(Person person, Node rootNode, Vector3f location);
	public abstract int getWeaponFlag();

}
